

#include "common.h"

// 串口的初始化
int init_serial(const char *file, int baudrate)
{
    int fd;

    fd = open(file, O_RDWR);
    if (fd == -1)
    {
        perror("open device error:");
        return -1;
    }

    struct termios myserial;
    // 清空结构体
    memset(&myserial, 0, sizeof(myserial));
    // O_RDWR
    myserial.c_cflag |= (CLOCAL | CREAD);
    // 设置控制模式状态，本地连接，接受使能
    // 设置 数据位
    myserial.c_cflag &= ~CSIZE;   // 清空数据位
    myserial.c_cflag &= ~CRTSCTS; // 无硬件流控制
    myserial.c_cflag |= CS8;      // 数据位:8

    myserial.c_cflag &= ~CSTOPB; //   //1位停止位
    myserial.c_cflag &= ~PARENB; // 不要校验
    // myserial.c_iflag |= IGNPAR;   //不要校验
    // myserial.c_oflag = 0;  //输入模式
    // myserial.c_lflag = 0;  //不激活终端模式

    switch (baudrate)
    {
    case 9600:
        cfsetospeed(&myserial, B9600); // 设置波特率
        cfsetispeed(&myserial, B9600);
        break;
    case 115200:
        cfsetospeed(&myserial, B115200); // 设置波特率
        cfsetispeed(&myserial, B115200);
        break;
    case 19200:
        cfsetospeed(&myserial, B19200); // 设置波特率
        cfsetispeed(&myserial, B19200);
        break;
    }

    /* 刷新输出队列,清除正接受的数据 */
    tcflush(fd, TCIFLUSH);

    /* 改变配置 */
    tcsetattr(fd, TCSANOW, &myserial);

    return fd;
}

// 解析数据
void parse_data(unsigned char buf[], int n,Data* data)
{
    if (buf[2] == 0x15)
    {
         double lux = (buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7])/100.0;
         //printf("lux %.2f\n",lux / 100);
         data->lux = lux;
         if(lux>1000) bled_ctrl(BEEP,1);
         else  bled_ctrl(BEEP,0);
    }
    else if (buf[2] == 0x45)
    {
        double tem,press,humid,height;
        tem = buf[4] << 8 | buf[5];
        tem /= 100;

        press = buf[6] << 24 | buf[7] << 16 | buf[8] << 8 | buf[9];
        press /= 100000;

        humid = buf[10] << 8 | buf[11];
        humid /= 100;

        height = buf[12] << 8 | buf[13];

        //printf("tempuratue %.2f degree pressure %.2f pa humidity %.2f %% height %.2f m\n",tem,press,humid,height);
        data->tem = tem;
        data->press = press;
        data->humid = humid;
        data->height = height;

    }
}

// 获取GY39传感器数据
void* get_gy39(void *arg)
{
    // 1.打开串口并初始化
    int fd = init_serial(COM2, 9600);
    if (fd == -1)
    {
        return NULL;
    }

    // 2.发送指令
    unsigned char cmd[3] = {0xA5, 0x83, 0x28};
    write(fd, cmd, 3);

    unsigned char buf[15] = {0};
    unsigned char ch;

    while (1)
    {
        // 3.接收数据
        // 先读取第一个0x5A
        do
        {
            read(fd, &ch, 1);
        } while (ch != 0x5A);

        // 读取第二个0x5A
        read(fd, &ch, 1);
        if (ch != 0x5A)
        {
            continue;
        }

        int i = 0;
        buf[0] = 0x5A;
        buf[1] = 0x5A;

        // 读取 “数据类型”
        read(fd, &buf[2], 1);

        // 读取 “数据长度”
        read(fd, &buf[3], 1);

        // 读取 传感器数据内容
        int len = buf[3];
        for (i = 0; i < len; i++)
        {
            read(fd, &buf[4 + i], 1);
        }

        // 读取 校验和
        read(fd, &buf[4 + len], 1);


        sleep(1);
        parse_data(buf, len + 5,arg);

        // 4.解析数据，并显示
        // 根据手册解析buf数组里面的数据
    }
    close(fd);
    // 5.关闭串口
}
